package com.rustic.server.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.xy.base.server.enums.RoleEnum;
import cn.xy.base.server.po.SysAdmin;
import cn.xy.base.server.service.SysAdminService;
import cn.xy.base.server.utils.PageUtil;
import cn.xy.commons.constant.Consts;
import cn.xy.commons.enums.DisableStatus;
import cn.xy.commons.exception.JzRuntimeException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rustic.server.dao.RusticDao;
import com.rustic.server.enums.LinkType;
import com.rustic.server.po.Rustic;
import com.rustic.server.po.RusticAdmin;
import com.rustic.server.po.UserCollectionLink;
import com.rustic.server.po.UserLikeLink;
import com.rustic.server.query.RusticAdminListQuery;
import com.rustic.server.query.RusticUserListQuery;
import com.rustic.server.service.RusticAdminService;
import com.rustic.server.service.RusticService;
import com.rustic.server.service.UserBrowseLinkService;
import com.rustic.server.service.UserCollectionLinkService;
import com.rustic.server.service.UserLikeLinkService;
import com.rustic.server.vo.list.RusticAdminListVO;
import com.rustic.server.vo.list.RusticWebListVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Rustic对应的服务类实现
 *
 * @author auto
 */

@Service
public class RusticServiceImpl extends ServiceImpl<RusticDao, Rustic> implements RusticService {

    @Autowired
    private SysAdminService sysAdminService;

    @Autowired
    private RusticAdminService rusticAdminService;

    @Autowired
    private UserLikeLinkService userLikeLinkService;

    @Autowired
    private UserCollectionLinkService userCollectionLinkService;

    @Autowired
    private UserBrowseLinkService userBrowseLinkService;

    @Override
    public List<Rustic> listByIdIn(List<Integer> idList) {
        if (CollUtil.isEmpty(idList)) {
            return new ArrayList<>();
        }
        return this.listByIds(idList);
    }

    @Override
    public Map<Integer, Rustic> mapByIdIn(List<Integer> idList) {
        List<Rustic> rusticList = this.listByIdIn(idList);
        return rusticList.stream().collect(Collectors.toMap(Rustic::getId, b -> b));
    }

    @Override
    public LambdaQueryWrapper<Rustic> toAdminListWrapper(RusticAdminListQuery query, List<Integer> rusticIdList, int roleId) {
        LambdaQueryWrapper<Rustic> queryWrapper = new LambdaQueryWrapper<>();
        //FIXME 根据需要修改搜索条件
        queryWrapper.like(CharSequenceUtil.isNotEmpty(query.getName()), Rustic::getName, query.getName());
        queryWrapper.like(CharSequenceUtil.isNotEmpty(query.getAddress()), Rustic::getAddress, query.getAddress());
        queryWrapper.eq(query.getStatus() > 0, Rustic::getStatus, query.getStatus());
        queryWrapper.gt(query.getStartCreateTime() != null, Rustic::getCreateTime, query.getStartCreateTime());
        queryWrapper.lt(query.getEndCreateTime() != null, Rustic::getCreateTime, query.getEndCreateTime());

        // 乡村id列表
        if (roleId != RoleEnum.SUPER_ADMIN.getId()) {
            if (CollUtil.isEmpty(rusticIdList)) {
                return null;
            }
            queryWrapper.in(CollUtil.isNotEmpty(rusticIdList), Rustic::getId, rusticIdList);
        }
        // 默认按照创建时间倒叙
        queryWrapper.orderByDesc(Rustic::getCreateTime);
        return queryWrapper;
    }

    @Override
    public List<RusticAdminListVO> toAdminListVo(List<Rustic> rusticList) {
        List<RusticAdminListVO> results = new ArrayList<>();
        for (Rustic rustic : rusticList) {
            RusticAdminListVO rusticAdminListVO = new RusticAdminListVO(rustic);
            results.add(rusticAdminListVO);
        }
        return results;
    }

    public Page<RusticAdminListVO> getAdminPageList(RusticAdminListQuery query, int adminId) {
        // 要是该管理员的角色id为1的时候展示所有的乡村
        // 若角色id不为1，先查询管理员相关的乡村然后再按条件展示出来2
        SysAdmin sysAdmin = sysAdminService.getById(adminId);
        if (sysAdmin == null) {
            return new Page<>();
        }
        List<Integer> rusticIdList = new ArrayList<>();
        // 角色不为1的
        if (sysAdmin.getRoleId() != RoleEnum.SUPER_ADMIN.getId()) {
            // 获得关联乡村的id列表
            rusticIdList = rusticAdminService.getRusticIdByAdminId(adminId);
        }
        LambdaQueryWrapper<Rustic> queryWrapper = this.toAdminListWrapper(query, rusticIdList, sysAdmin.getRoleId());
        if (queryWrapper == null) {
            return new Page<>();
        }
        Page<Rustic> pageData = this.page(query.toPage(), queryWrapper);
        List<Rustic> rusticList = pageData.getRecords();
        if (CollUtil.isEmpty(rusticList)) {
            return new Page<>();
        }
        List<RusticAdminListVO> results = this.toAdminListVo(rusticList);
        return PageUtil.toPage(pageData, results);
    }

    @Override
    public List<RusticWebListVO> toWebListVo(List<Rustic> rusticList, int userId) {
        List<Integer> rusticIdList = rusticList.stream().map(Rustic::getId).collect(Collectors.toList());
        Map<Integer, Long> likeCountMap = userLikeLinkService.mapByTargetIdAndType(rusticIdList, LinkType.RUSTIC);
        Map<Integer, Long> collectionCountMap = userCollectionLinkService.mapByTargetIdAndType(rusticIdList, LinkType.RUSTIC);
        Map<Integer, Long> browseCountMap = userBrowseLinkService.mapByTargetIdAndType(rusticIdList, LinkType.RUSTIC);
        // 用户是否有点赞收藏
        Map<Integer, UserLikeLink> userLikeMap = userLikeLinkService.mapByUserTargetAndType(rusticIdList, LinkType.RUSTIC, userId);
        Map<Integer, UserCollectionLink> userCollectionMap = userCollectionLinkService.mapByUserTargetAndType(rusticIdList, LinkType.RUSTIC, userId);
        return rusticList.stream().map(item -> {
            RusticWebListVO rusticWebListVO = new RusticWebListVO(item);
            // 得到点赞的数量
            if (likeCountMap.get(item.getId()) != null) {
                rusticWebListVO.setLikeCount(likeCountMap.get(item.getId()));
            }
            // 收藏的数量
            if (collectionCountMap.get(item.getId()) != null) {
                rusticWebListVO.setCollectionCount(collectionCountMap.get(item.getId()));
            }
            // 浏览数量
            if (browseCountMap.get(item.getId()) != null) {
                rusticWebListVO.setBrowseCount(browseCountMap.get(item.getId()));
            }
            // 用户是否点赞
            if (userLikeMap.get(item.getId()) != null) {
                rusticWebListVO.setLike(true);
            }
            // 用户是否收藏
            if (userCollectionMap.get(item.getId()) != null) {
                rusticWebListVO.setCollection(true);
            }
            return rusticWebListVO;
        }).collect(Collectors.toList());
    }

    @Override
    public void isRusticAdmin(int rusticId, int adminId) {
        SysAdmin sysAdmin = sysAdminService.getById(adminId);
        if (sysAdmin == null) {
            throw new JzRuntimeException(Consts.NOT_FOUND, SysAdminService.SYS_ADMIN_NOT_EXIST);
        }
        // 运营管理员不能禁用乡村
        if (sysAdmin.getRoleId() == RoleEnum.OPERATION_ADMIN.getId()) {
            throw new JzRuntimeException("运营管理员不能禁用乡村");
        }
        if (sysAdmin.getRoleId() == RoleEnum.RUSTIC_ADMIN.getId()) {
            // 判断对应的乡村是否有权限禁用启用
            RusticAdmin rusticAdmin = rusticAdminService.getByAdminIdAndRusticId(adminId, rusticId);
            if (rusticAdmin == null) {
                throw new JzRuntimeException("您在该乡村的管理权限不足");
            }
            if (rusticAdmin.getRoleId() != RoleEnum.RUSTIC_ADMIN.getId()) {
                throw new JzRuntimeException("您在该乡村的管理权限不足");
            }
        }
    }

    @Override
    public void disable(int rusticId, int adminId) {
        // 判断是否有权限修改
        this.isRusticAdmin(rusticId, adminId);
        // 修改状态
        Rustic rustic = this.getById(rusticId);
        if (rustic == null) {
            throw new JzRuntimeException(Consts.NOT_FOUND, RusticService.RUSTIC_NOT_EXIST);
        }
        rustic.setStatus(DisableStatus.negate(rustic.getStatus()));
        this.updateById(rustic);
    }

    @Override
    public LambdaQueryWrapper<Rustic> toUserListWrapper(RusticUserListQuery query) {
        LambdaQueryWrapper<Rustic> wrapper = new LambdaQueryWrapper<>();
        // 自定义字段避免获取富文本字段
        wrapper.select(Rustic::getId, Rustic::getMobile, Rustic::getName, Rustic::getBriefIntro, Rustic::getAddress,
                Rustic::getDetailedAddress, Rustic::getCover, Rustic::getUpdateTime, Rustic::getCreateTime);
        wrapper.like(CharSequenceUtil.isNotEmpty(query.getName()), Rustic::getName, query.getName());
        wrapper.like(CharSequenceUtil.isNotEmpty(query.getAddress()), Rustic::getAddress, query.getAddress());
        wrapper.eq(Rustic::getStatus, DisableStatus.NORMAL.getValue());
        wrapper.orderByDesc(Rustic::getUpdateTime);
        return wrapper;
    }
}
